package com.yc.boottxx.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yc.boottxx.entity.User;
import com.yc.boottxx.mapper.UserMapper;
import com.yc.boottxx.service.BizException;
import com.yc.boottxx.service.IUserService;
import com.yc.boottxx.util.QRCodeUtils;
import com.yc.boottxx.util.Utils;
import com.yc.boottxx.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
//import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 天下行租车-用户表-4 前端控制器
 * </p>
 *
 * @author xl
 * @since 2024-05-07
 */
@RestController
@RequestMapping("/txx/user")
public class UserController {

    @Autowired
    IUserService userService;

    @Autowired
    UserMapper userMapper;

    //  Bean named 'redisTemplate' is expected to be of type
    //  'org.springframework.data.redis.core.StringRedisTemplate'
    //  but was actually of type 'org.springframework.data.redis.core.RedisTemplate'
    @Resource(name = "stringRedisTemplate")
    StringRedisTemplate redisTemplate;

    @RequestMapping("login")
    public Result login(User user, HttpSession session) throws BizException {
            user = userService.login(user);
            session.setAttribute("loginedUser",user);
            return Result.ok("登录成功!",user);
    }

    @RequestMapping("myinfo")
    public Result myinfo(@SessionAttribute(required = false) User loginedUser) {
        if(loginedUser == null) {
            return Result.fail("请登录系统");
        } else {
            return Result.ok("已登录",loginedUser);
        }
    }

    @RequestMapping("logout")
    public ModelAndView logout(ModelAndView mav, HttpSession session) {
        session.invalidate();
        // 这里不需要加 上下文路径,
        String path = "redirect:/index.html";
        System.out.println("path = " + path);
        mav.setViewName(path);
        return mav;
    }

    @RequestMapping("reg")
    public Result register(@RequestBody @Valid User user, Errors errors) throws BizException {
        if(errors.hasErrors()) {
            return Result.fail("字段验证失败",errors.getAllErrors());
        }
        try {
            userService.register(user);
            return Result.ok("注册成功");
        } catch (BizException e) {
            String fieldName = e.getData().toString();
            errors.rejectValue(fieldName,fieldName + ".exists",e.getMessage());
            throw new BizException("字段验证失败",errors.getAllErrors());
        }
    }

    @PostMapping("upload")
    public Result upload(@RequestParam("file") MultipartFile file) throws IOException {
        System.out.println("上传文件的字段名(请求参数) file.getName() = " + file.getName());
        System.out.println("上传文件名 file.getOriginalFilename() = " + file.getOriginalFilename());

        String newName = UUID.randomUUID().toString();
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        File fileObj = new File("D:\\yc三期项目\\新教学视频\\5.14\\upload\\" + newName + suffix);
        file.transferTo(fileObj);
        // 单文件上传
        return Result.ok("文件上传成功!",newName+suffix);
    }

    @PostMapping("upload1")
    public Result upload1(@RequestParam("file") MultipartFile[] file) throws IOException {

        for (MultipartFile multipartFile : file) {
            String newName = UUID.randomUUID().toString();
            String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
            File fileObj = new File("D:\\yc三期项目\\新教学视频\\5.14\\upload\\" + newName + suffix);
            multipartFile.transferTo(fileObj);
        }
        // 多文件上传
        return Result.ok("文件上传成功!");
    }

    @PostMapping("upload2")
    public Result upload2(@RequestParam("imagefile") MultipartFile imageFile,
                          @RequestParam("docFile") MultipartFile docFile) {
        // 多文件上传
        return null;
    }

    //Map<String,Object> qrMap = new Hashtable<>();
    private String logoPath = "D:\\yc\\images\\logo1.png";

    @RequestMapping(path = "createQr", produces = MediaType.IMAGE_PNG_VALUE)
    public void createQrcode(OutputStream out, HttpSession session) throws Exception{
        String qrcode = UUID.randomUUID().toString();
        // 存入扫码状态
        //qrMap.put(qrcode,0);
        putToRedis(qrcode,"0");
        session.setAttribute("qrcode",qrcode);
        String url = "http://192.168.31.96:8080/demo_txx_war_exploded/txx/user/scanQrcode?qrcode=" + qrcode;
        QRCodeUtils.encode(url,logoPath,out,false);
    }

    // 扫码方法
    @RequestMapping("scanQrcode")
        public Object scanQrcode(String qrcode,
                             @SessionAttribute(required = false) User loginedUser,
                                 ModelAndView mav) {
        if(loginedUser == null) {
            mav.setViewName("redirect:/login.html");
            return mav;
        }
        // 扫码成功, 保存用户信息
        //qrMap.put(qrcode,loginedUser);
        // json
        ObjectMapper mapper = new ObjectMapper();
        String json = null;
        try {
            json = mapper.writeValueAsString(loginedUser);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        putToRedis(qrcode,json);

        //System.out.println("-------------------qrMap = " + qrMap);
        return Result.ok("扫码成功!");
    }

    @RequestMapping("refreshQr")
    public Result refreshQr(@SessionAttribute(required = false) String qrcode,
                            HttpSession session) {
        if(qrcode == null) {
            return Result.fail("二维码还未生成");
        }
        //System.out.println("********************qrMap = " + qrMap);
        //Object object = qrMap.get(qrcode);
        String json = getFromRedis(qrcode);

        //if(object instanceof User) {
        if("0".equals(json) == false){
            ObjectMapper mapper = new ObjectMapper();
            User user;
            try {
                user = mapper.readValue(json, User.class);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            // 扫码登录成功
            //session.setAttribute("loginedUser",object);
            session.setAttribute("loginedUser",user);
            session.removeAttribute("qrcode");
            //qrMap.remove(qrcode);
            delFromRedis(qrcode);

            //return Result.ok("登录成功",object);
            return Result.ok("登录成功",user);
        } else {
//            return Result.fail("还未扫码",object);
            return Result.fail("还未扫码",null);
        }
    }

    public void putToRedis(String qrcode,String value){
//        try(Jedis jedis = new Jedis("127.0.0.1",6379);) {
//            jedis.set(qrcode,value);
//        }
        redisTemplate.opsForValue().set(qrcode,value);
    }

    public String getFromRedis(String qrcode){
//        try(Jedis jedis = new Jedis("127.0.0.1",6379);) {
//            return jedis.get(qrcode);
//        }
        return redisTemplate.opsForValue().get(qrcode);
    }

    public void delFromRedis(String qrcode){
//        try(Jedis jedis = new Jedis("127.0.0.1",6379);) {
//            jedis.del(qrcode);
//        }
        redisTemplate.delete(qrcode);
    }

    @RequestMapping("findById")
    public Result findById(String id){
        return Result.ok("找到用户信息",userMapper.selectById(id));
    }


    @RequestMapping("update")
    public Result update(User user,@SessionAttribute User loginedUser) throws BizException {
        userService.updateUserInfo(user);
        //更新用户基本信息
        loginedUser.setCname(user.getCname());
        loginedUser.setEamil(user.getEamil());
        loginedUser.setHeadimg(user.getHeadimg());
        return Result.ok("信息更新成功");
    }

    @RequestMapping("upPwd")
    public Result upPwd(User user,
                        String oldPwd,
                        String newPwd,
                        String vcode,
                        HttpSession session) throws BizException {
//        Object svcode = session.getAttribute("vcode");
//        // isBlank 空字符串 或者 空格字符串
//        Utils.check(vcode==null || vcode.isBlank(),"请输入验证码!");
//        Utils.check(vcode.equals(svcode) == false,"验证码输入错误!");

        user.setPassword(oldPwd);
        userService.upPwd(user,newPwd);//修改密码
        // 修改密码了，直接销毁。让用户重新登录
        session.invalidate();
        return Result.ok("密码修改成功");
    }

    @Resource
    JavaMailSender mailSender;

    @Value("${myMail}")
    String myMail;

    @GetMapping("sendUpPwdVcode")
    public Result sendUpPwdVcode(HttpSession session,
                                 @SessionAttribute User loginedUser){
        String vode = System.currentTimeMillis()+"";
        vode = vode.substring(vode.length() - 4);
        session.setAttribute("vcode", vode);
        // 文本邮件内容对象
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(myMail);
        message.setTo(loginedUser.getEamil());
        message.setSubject("重置密码验证码");
        message.setText("您重置密码的验证码是: " + vode);
        mailSender.send(message);
        return Result.ok("验证码发送成功!");
    }

}
